package ua.kratik.seabattle.game;

import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import ua.kratik.seabattle.game.enums.CellState;

public class AdmiralsMap extends SeaMap {

	private static Logger logger = LoggerFactory.getLogger(AdmiralsMap.class);

	/** 
	 * Ship can be found by coordinates of his alive part
	 * If ship is hit by enemy this part excludes from the aliveShips map
	 */
	private Map<Coordinates, Ship> aliveShips;

	private Map<Coordinates, Ship> allShips;
	
	public AdmiralsMap(int seaSizeX, int seaSizeY){
		super(seaSizeX, seaSizeY);
		
		aliveShips = new HashMap<Coordinates, Ship>();
		allShips = new HashMap<Coordinates, Ship>();

	}
	
	public Ship findShipOnCell(Coordinates c) {
		return allShips.get(c);
	}

	
	public void drawShip(Ship ship) {
		Coordinates[] c = ship.getPositionMap();
		int minX;
		int maxX;
		int minY;
		int maxY;
		if (c[0].getX() < c[c.length - 1].getX()) {
			minX = c[0].getX() - 1;
			maxX = c[c.length - 1].getX() + 1;
		} else {
			minX = c[c.length - 1].getX() - 1;
			maxX = c[0].getX() + 1;
		}

		if (c[0].getY() < c[c.length - 1].getY()) {
			minY = c[0].getY() - 1;
			maxY = c[c.length - 1].getY() + 1;
		} else {
			minY = c[c.length - 1].getY() - 1;
			maxY = c[0].getY() + 1;
		}

		if (minX < 1)
			minX = 1;
		if (maxX > getSeaSizeX())
			maxX = getSeaSizeX();
		if (minY < 1)
			minY = 1;
		if (maxY > getSeaSizeY())
			maxY = getSeaSizeY();

		// validation
		for (int y = minY; y <= maxY; y++) {
			for (int x = minX; x <= maxX; x++) {
				if (getCellState(x, y) == CellState.CONTAIN_SHIP) {
					StringBuilder sb = new StringBuilder();
					sb.append("Cell (x=");
					sb.append(x);
					sb.append("; y=");
					sb.append(y);
					sb.append(") has state: [");
					sb.append(getCellState(x, y));
					sb.append("]");
					logger.error(sb.toString());
					throw new IllegalArgumentException(
							"Coordinates are invalid. Cannot place ship here");
				}
			}
		}

		for (int y = minY; y <= maxY; y++) {
			for (int x = minX; x <= maxX; x++) {
				setCellState(x, y, CellState.CANNOT_CONTAIN_SHIP);
			}
		}

		for (Coordinates cc : c) {
			setCellState(cc.getX(), cc.getY(), CellState.CONTAIN_SHIP);
			aliveShips.put(cc, ship);
			allShips.put(cc, ship);
			logger.debug("ship " + ship.getShipBean().getName()
					+ "was plased to cell " + cc);
			logger.trace("alliveShips [" + aliveShips.size() + "]: "
					+ aliveShips);
			logger.trace("allShipCells [" + allShips.size() + "]: "
					+ allShips);
		}
		if (logger.isTraceEnabled()) {
			logger.trace("New ship was drew:\n" + this.toString());
		}
	}
	
	
	@Override
	public void cleanMap(){
		logger.debug("Cleaning map to state EMPTY");
		aliveShips.clear();
		allShips.clear();
		super.fillWholeMap(CellState.EMPTY);
	}

}
